<template>
    <div class="game-stage">
        <div ref="container" class="three-container"></div>
        <UI :player1Health="gameState.player1.health" :player2Health="gameState.player2.health" :round="gameState.round"
            :time="gameState.time" @back-to-menu="$emit('back-to-menu')" />
        <!-- 技能UI界面 -->
        <div class="skills-ui">
            <div class="skill-section">
                <h3>移动控制</h3>
                <div class="skill-row">
                    <div class="skill-key">W</div>
                    <span>跳跃</span>
                </div>
                <div class="skill-row">
                    <div class="skill-key">A</div>
                    <span>左移</span>
                </div>
                <div class="skill-row">
                    <div class="skill-key">D</div>
                    <span>右移</span>
                </div>
                <div class="skill-row">
                    <div class="skill-key">S</div>
                    <span>后退</span>
                </div>
            </div>
            <div class="skill-section">
                <h3>战斗技能</h3>
                <div class="skill-row">
                    <div class="skill-key" :class="{ 'cooldown': getAttackCooldown() > 0 }">
                        F
                        <div v-if="getAttackCooldown() > 0" class="cooldown-mask">
                            <span class="cooldown-num">{{ Math.ceil(getAttackCooldown()) }}</span>
                        </div>
                    </div>
                    <span>普通攻击</span>
                </div>
                <div class="skill-row">
                    <div class="skill-key" :class="{ 'cooldown': getSuperCooldown() > 0 }">
                        G
                        <div v-if="getSuperCooldown() > 0" class="cooldown-mask">
                            <span class="cooldown-num">{{ Math.ceil(getSuperCooldown()) }}</span>
                        </div>
                    </div>
                    <span>大招技能</span>
                </div>
            </div>
        </div>
        <div v-if="gameState.gameOver" class="next-level-modal">
            <div class="modal-content">
                <div class="modal-title">游戏结束！</div>
                <button class="next-btn" @click="$emit('next-level')">下一关</button>
                <button class="back-btn" @click="$emit('back-to-menu')">返回菜单</button>
            </div>
        </div>
    </div>
</template>

<script>
import { ref, onMounted, onUnmounted, reactive } from 'vue'
import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'
import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass.js'
import { OutputPass } from 'three/examples/jsm/postprocessing/OutputPass.js'
import UI from './UI.vue'

// 预加载资源
import streetBg from '@/assets/textures/street_preview.png'
import dojoBg from '@/assets/textures/dojo_preview.png'
import volcanoBg from '@/assets/textures/volcano_preview.png'

export default {
    components: { UI },
    props: {
        selectedLevel: {
            type: Object,
            required: true
        }
    },
    setup(props, { emit }) {
        // 非响应式的 Three.js 对象
        const threeState = {
            scene: new THREE.Scene(),
            camera: new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000),
            renderer: new THREE.WebGLRenderer({ antialias: true, alpha: true }),
            clock: new THREE.Clock(),
            mixer1: null,
            mixer2: null,
            composer: null,
            character1: null,
            character2: null,
            animationFrameId: null
        }

        // 响应式的游戏状态
        const gameState = reactive({
            player1: {
                health: 100,
                position: { x: -3, y: 1, z: 0 },
                rotation: { y: Math.PI / 2 },
                state: 'idle',
                attacks: []
            },
            player2: {
                health: 100,
                position: { x: 3, y: 1, z: 0 },
                rotation: { y: -Math.PI / 2 },
                state: 'idle',
                attacks: []
            },
            round: 1,
            time: 99,
            gameOver: false
        })

        const container = ref(null)

        // 键盘控制状态，支持三维移动和大招
        const keyState = reactive({
            a: false, d: false, w: false, s: false, // 玩家1
            j: false, l: false, i: false, k: false, // 玩家2
            f: false, h: false, // 普通攻击
            g: false, u: false  // 大招
        })

        // 粒子特效列表
        const attackEffects = ref([]) // { mesh, timeLeft }

        // 攻击相关状态
        const ATTACK_RANGE = 2.5 // 攻击距离
        const ATTACK_DAMAGE = 10 // 每次攻击伤害
        const ATTACK_COOLDOWN = 0.5 // 秒
        const attackState = reactive({
            p1LastAttack: 0,
            p2LastAttack: 0
        })

        // 玩家移动速度
        const MOVE_SPEED = 5 // 单位/秒

        // 大招相关状态
        const SUPER_COOLDOWN = 5 // 秒
        const SUPER_DAMAGE = 30
        const SUPER_RANGE = 4
        const superState = reactive({
            p1LastSuper: 0,
            p2LastSuper: 0
        })

        // 受击闪烁状态
        const hitFlash = reactive({
            p1: 0,
            p2: 0
        })

        // 边界限制
        const BOUNDS = { x: 12, z: 7 }

        // 跳跃相关状态
        const GRAVITY = 18
        const JUMP_VELOCITY = 9
        const groundY = 1 // 站立高度
        const jumpState = reactive({
            p1VelY: 0,
            p2VelY: 0,
            p1OnGround: true,
            p2OnGround: true
        })

        // 攻击拖尾和冲击波特效
        const attackTrails = ref([]) // { mesh, timeLeft }
        const impactWaves = ref([]) // { mesh, timeLeft }

        // AI状态
        const aiState = reactive({
            attackCooldown: 0,
            superCooldown: 0,
            jumpCooldown: 0,
            moveDir: 1 // 1为右，-1为左
        })

        // 初始化场景
        const initScene = async () => {
            try {
                const { scene, camera, renderer } = threeState

                renderer.setSize(window.innerWidth, window.innerHeight)
                renderer.shadowMap.enabled = true
                renderer.shadowMap.type = THREE.PCFSoftShadowMap
                container.value.appendChild(renderer.domElement)

                // 调整相机位置，确保能看到角色
                camera.position.set(0, 8, 12)
                camera.lookAt(0, 0, 0)

                // 添加灯光
                const ambientLight = new THREE.AmbientLight(0x404040, 0.6)
                scene.add(ambientLight)

                const directionalLight = new THREE.DirectionalLight(0xffffff, 1.0)
                directionalLight.position.set(10, 20, 10)
                directionalLight.castShadow = true
                directionalLight.shadow.mapSize.width = 2048
                directionalLight.shadow.mapSize.height = 2048
                scene.add(directionalLight)

                // 根据选择的关卡加载场景
                await loadLevelScene(props.selectedLevel.scene)

                // 加载角色
                await loadCharacters()

                // 后期处理效果
                initPostProcessing()

                // 开始动画循环
                animate()
            } catch (error) {
                console.error('初始化场景失败:', error)
            }
        }

        // 初始化后期处理
        const initPostProcessing = () => {
            const { renderer, scene, camera } = threeState
            threeState.composer = new EffectComposer(renderer)

            const renderPass = new RenderPass(scene, camera)
            threeState.composer.addPass(renderPass)

            const outputPass = new OutputPass()
            threeState.composer.addPass(outputPass)
        }

        // 加载关卡场景
        const loadLevelScene = async (sceneType) => {
            const { scene } = threeState

            // 创建格斗场地（更明显）
            const groundGeometry = new THREE.PlaneGeometry(30, 20)
            const groundMaterial = new THREE.MeshStandardMaterial({
                color: 0x222222,
                roughness: 0.8,
                metalness: 0.2
            })
            const ground = new THREE.Mesh(groundGeometry, groundMaterial)
            ground.rotation.x = -Math.PI / 2
            ground.position.y = -0.5
            ground.receiveShadow = true
            scene.add(ground)

            // 场地边界线
            const borderGeometry = new THREE.EdgesGeometry(groundGeometry)
            const borderMaterial = new THREE.LineBasicMaterial({ color: 0xffcc00, linewidth: 2 })
            const border = new THREE.LineSegments(borderGeometry, borderMaterial)
            border.rotation.x = -Math.PI / 2
            border.position.y = -0.49
            scene.add(border)

            // 场地中心圆圈
            const circleGeometry = new THREE.RingGeometry(2, 2.2, 32)
            const circleMaterial = new THREE.MeshBasicMaterial({ color: 0xffcc00, side: THREE.DoubleSide, transparent: true, opacity: 0.6 })
            const circle = new THREE.Mesh(circleGeometry, circleMaterial)
            circle.rotation.x = -Math.PI / 2
            circle.position.y = -0.48
            scene.add(circle)

            // 使用预加载的背景纹理
            const bgTextures = {
                streetScene: streetBg,
                dojoScene: dojoBg,
                volcanoScene: volcanoBg
            }

            const bgTexture = new THREE.TextureLoader().load(bgTextures[sceneType])
            bgTexture.encoding = THREE.sRGBEncoding

            // 添加背景 - 调整位置避免遮挡角色
            const bgGeometry = new THREE.BoxGeometry(100, 50, 1)
            const bgMaterial = new THREE.MeshBasicMaterial({
                map: bgTexture,
                side: THREE.BackSide
            })
            const background = new THREE.Mesh(bgGeometry, bgMaterial)
            background.position.z = -50
            scene.add(background)
        }

        // 美化角色，丰满造型
        const createSimpleCharacter = (color, position) => {
            const group = new THREE.Group()
            // 身体（胸部+腰部）
            const chestGeometry = new THREE.BoxGeometry(1.2, 1.1, 0.7)
            const chestMaterial = new THREE.MeshStandardMaterial({ color, metalness: 0.2, roughness: 0.6 })
            const chest = new THREE.Mesh(chestGeometry, chestMaterial)
            chest.position.set(0, 1.5, 0)
            chest.castShadow = true
            chest.name = 'body'
            group.add(chest)
            // 腰部
            const waistGeometry = new THREE.BoxGeometry(0.8, 0.6, 0.5)
            const waistMaterial = new THREE.MeshStandardMaterial({ color: 0x333333 })
            const waist = new THREE.Mesh(waistGeometry, waistMaterial)
            waist.position.set(0, 1.0, 0)
            waist.castShadow = true
            group.add(waist)
            // 腰带
            const beltGeometry = new THREE.TorusGeometry(0.42, 0.08, 8, 16)
            const beltMaterial = new THREE.MeshStandardMaterial({ color: 0xffcc00 })
            const belt = new THREE.Mesh(beltGeometry, beltMaterial)
            belt.position.set(0, 1.0, 0)
            belt.rotation.x = Math.PI / 2
            group.add(belt)
            // 头
            const headGeometry = new THREE.SphereGeometry(0.5, 32, 32)
            const headMaterial = new THREE.MeshStandardMaterial({ color: 0xffe0b2, roughness: 0.5 })
            const head = new THREE.Mesh(headGeometry, headMaterial)
            head.position.set(0, 2.25, 0)
            head.castShadow = true
            group.add(head)
            // 发带
            const bandGeometry = new THREE.TorusGeometry(0.32, 0.06, 8, 16)
            const bandMaterial = new THREE.MeshStandardMaterial({ color: color === 0xff0000 ? 0xffffff : 0x2222ff })
            const band = new THREE.Mesh(bandGeometry, bandMaterial)
            band.position.set(0, 2.38, 0)
            band.rotation.x = Math.PI / 2
            group.add(band)
            // 眼睛
            const eyeGeometry = new THREE.SphereGeometry(0.07, 16, 16)
            const eyeMaterial = new THREE.MeshStandardMaterial({ color: 0x222222 })
            const leftEye = new THREE.Mesh(eyeGeometry, eyeMaterial)
            leftEye.position.set(-0.16, 2.32, 0.38)
            const rightEye = new THREE.Mesh(eyeGeometry, eyeMaterial)
            rightEye.position.set(0.16, 2.32, 0.38)
            group.add(leftEye)
            group.add(rightEye)
            // 肩膀
            const shoulderGeometry = new THREE.SphereGeometry(0.23, 16, 16)
            const shoulderMaterial = new THREE.MeshStandardMaterial({ color: color === 0xff0000 ? 0xff8888 : 0x8888ff })
            const leftShoulder = new THREE.Mesh(shoulderGeometry, shoulderMaterial)
            leftShoulder.position.set(-0.8, 1.85, 0)
            group.add(leftShoulder)
            const rightShoulder = new THREE.Mesh(shoulderGeometry, shoulderMaterial)
            rightShoulder.position.set(0.8, 1.85, 0)
            group.add(rightShoulder)
            // 手臂（加粗）
            const armGeometry = new THREE.BoxGeometry(0.38, 1.2, 0.38)
            const armMaterial = new THREE.MeshStandardMaterial({ color: color === 0xff0000 ? 0xff8888 : 0x8888ff })
            const leftArm = new THREE.Mesh(armGeometry, armMaterial)
            leftArm.position.set(-1.05, 1.3, 0)
            leftArm.castShadow = true
            leftArm.name = 'leftArm'
            group.add(leftArm)
            const rightArm = new THREE.Mesh(armGeometry, armMaterial)
            rightArm.position.set(1.05, 1.3, 0)
            rightArm.castShadow = true
            rightArm.name = 'rightArm'
            group.add(rightArm)
            // 拳套
            const gloveGeometry = new THREE.SphereGeometry(0.22, 16, 16)
            const gloveMaterial = new THREE.MeshStandardMaterial({ color: color === 0xff0000 ? 0xcc0000 : 0x0000cc })
            const leftGlove = new THREE.Mesh(gloveGeometry, gloveMaterial)
            leftGlove.position.set(-1.05, 0.7, 0)
            group.add(leftGlove)
            const rightGlove = new THREE.Mesh(gloveGeometry, gloveMaterial)
            rightGlove.position.set(1.05, 0.7, 0)
            group.add(rightGlove)
            // 腿（加粗）
            const legGeometry = new THREE.BoxGeometry(0.38, 1.1, 0.38)
            const legMaterial = new THREE.MeshStandardMaterial({ color: color === 0xff0000 ? 0x880000 : 0x000088 })
            const leftLeg = new THREE.Mesh(legGeometry, legMaterial)
            leftLeg.position.set(-0.35, 0.25, 0)
            leftLeg.castShadow = true
            group.add(leftLeg)
            const rightLeg = new THREE.Mesh(legGeometry, legMaterial)
            rightLeg.position.set(0.35, 0.25, 0)
            rightLeg.castShadow = true
            group.add(rightLeg)
            // 位置
            group.position.copy(position)
            group.castShadow = true
            group.receiveShadow = true
            return group
        }

        // 加载角色
        const loadCharacters = () => {
            const { scene } = threeState
            const { player1, player2 } = gameState

            console.log('开始加载角色...')
            console.log('玩家1位置:', player1.position)
            console.log('玩家2位置:', player2.position)

            // 创建红色玩家1
            threeState.character1 = createSimpleCharacter(
                0xff0000,
                new THREE.Vector3(
                    player1.position.x,
                    player1.position.y,
                    player1.position.z
                )
            )
            threeState.character1.rotation.y = player1.rotation.y
            scene.add(threeState.character1)
            console.log('玩家1角色已添加到场景')

            // 创建蓝色玩家2
            threeState.character2 = createSimpleCharacter(
                0x0000ff,
                new THREE.Vector3(
                    player2.position.x,
                    player2.position.y,
                    player2.position.z
                )
            )
            threeState.character2.rotation.y = player2.rotation.y
            scene.add(threeState.character2)
            console.log('玩家2角色已添加到场景')

            console.log('场景中的对象数量:', scene.children.length)
        }

        // 改造tryAttack，普通攻击球带拖尾，命中时对方身上出现冲击波
        function tryAttack(attacker, defender, now, lastAttackKey, setLastAttack, dir) {
            if (now - lastAttackKey.value < ATTACK_COOLDOWN) return // 冷却中
            setLastAttack(now)
            // 攻击点
            const attackX = attacker.position.x + dir * ATTACK_RANGE
            const attackZ = attacker.position.z
            // 剑气特效
            const slashGeometry = new THREE.PlaneGeometry(2, 0.8)
            const slashMaterial = new THREE.MeshStandardMaterial({
                color: dir === 1 ? 0xff6666 : 0x6666ff,
                emissive: dir === 1 ? 0xff0000 : 0x0000ff,
                emissiveIntensity: 0.8,
                transparent: true,
                opacity: 0.9,
                side: THREE.DoubleSide
            })
            const slash = new THREE.Mesh(slashGeometry, slashMaterial)
            slash.position.set(attackX, attacker.position.y + 1.2, attackZ)
            slash.rotation.y = dir === 1 ? 0 : Math.PI
            slash.castShadow = true
            threeState.scene.add(slash)
            attackEffects.value.push({ mesh: slash, timeLeft: 0.2 })
            // 拖尾
            for (let i = 1; i <= 3; i++) {
                const tgeo = new THREE.PlaneGeometry(1.5 - i * 0.3, 0.6 - i * 0.1)
                const tmat = new THREE.MeshStandardMaterial({
                    color: slashMaterial.color,
                    transparent: true,
                    opacity: 0.6 - i * 0.2,
                    side: THREE.DoubleSide
                })
                const tmesh = new THREE.Mesh(tgeo, tmat)
                tmesh.position.set(attackX - dir * i * 0.4, attacker.position.y + 1.2, attackZ)
                tmesh.rotation.y = dir === 1 ? 0 : Math.PI
                threeState.scene.add(tmesh)
                attackTrails.value.push({ mesh: tmesh, timeLeft: 0.15 })
            }
            // 判定
            if (Math.abs(defender.position.x - attackX) < 1.5 && Math.abs(defender.position.z - attackZ) < 1.5) {
                defender.health -= ATTACK_DAMAGE
                if (defender.health < 0) defender.health = 0
                // 冲击波
                const waveGeo = new THREE.RingGeometry(0.2, 0.8, 32)
                const waveMat = new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide, transparent: true, opacity: 0.8 })
                const wave = new THREE.Mesh(waveGeo, waveMat)
                wave.position.set(defender.position.x, defender.position.y + 1.2, defender.position.z)
                wave.rotation.x = -Math.PI / 2
                threeState.scene.add(wave)
                impactWaves.value.push({ mesh: wave, timeLeft: 0.3 })
            }
        }

        // 粒子特效更新和清理
        function updateAttackEffects(delta) {
            for (let i = attackEffects.value.length - 1; i >= 0; i--) {
                attackEffects.value[i].timeLeft -= delta
                if (attackEffects.value[i].timeLeft <= 0) {
                    threeState.scene.remove(attackEffects.value[i].mesh)
                    attackEffects.value.splice(i, 1)
                }
            }
        }

        // 拖尾和冲击波特效更新
        function updateAttackTrails(delta) {
            for (let i = attackTrails.value.length - 1; i >= 0; i--) {
                attackTrails.value[i].timeLeft -= delta
                if (attackTrails.value[i].timeLeft <= 0) {
                    threeState.scene.remove(attackTrails.value[i].mesh)
                    attackTrails.value.splice(i, 1)
                }
            }
            for (let i = impactWaves.value.length - 1; i >= 0; i--) {
                impactWaves.value[i].timeLeft -= delta
                impactWaves.value[i].mesh.scale.x += delta * 4
                impactWaves.value[i].mesh.scale.y += delta * 4
                impactWaves.value[i].mesh.material.opacity -= delta * 2
                if (impactWaves.value[i].timeLeft <= 0) {
                    threeState.scene.remove(impactWaves.value[i].mesh)
                    impactWaves.value.splice(i, 1)
                }
            }
        }

        // 大招特效增强：命中爆炸+光环
        function trySuper(attacker, defender, now, lastSuperKey, setLastSuper, dir) {
            if (now - lastSuperKey.value < SUPER_COOLDOWN) return // 冷却中
            setLastSuper(now)
            // 大招球体
            const geometry = new THREE.SphereGeometry(1.5, 32, 32)
            const material = new THREE.MeshStandardMaterial({
                color: dir === 1 ? 0xffe066 : 0x66aaff,
                emissive: dir === 1 ? 0xffc300 : 0x0055ff,
                emissiveIntensity: 1.2,
                transparent: true,
                opacity: 0.9
            })
            const mesh = new THREE.Mesh(geometry, material)
            const attackX = attacker.position.x + dir * SUPER_RANGE
            const attackZ = attacker.position.z
            mesh.position.set(attackX, attacker.position.y + 1.2, attackZ)
            mesh.castShadow = true
            threeState.scene.add(mesh)
            attackEffects.value.push({ mesh, timeLeft: 0.6 })
            // 多层光环
            for (let i = 0; i < 3; i++) {
                const ringGeo = new THREE.TorusGeometry(1.6 + i * 0.3, 0.1, 8, 32)
                const ringMat = new THREE.MeshStandardMaterial({
                    color: dir === 1 ? 0xfff2a0 : 0xa0cfff,
                    emissive: dir === 1 ? 0xffc300 : 0x0055ff,
                    emissiveIntensity: 0.8,
                    transparent: true,
                    opacity: 0.6
                })
                const ring = new THREE.Mesh(ringGeo, ringMat)
                ring.position.set(attackX, attacker.position.y + 1.2, attackZ)
                ring.rotation.x = Math.PI / 2
                threeState.scene.add(ring)
                attackEffects.value.push({ mesh: ring, timeLeft: 0.6 })
            }
            // 判定
            if (Math.abs(defender.position.x - attackX) < 2.5 && Math.abs(defender.position.z - attackZ) < 2.5) {
                defender.health -= SUPER_DAMAGE
                if (defender.health < 0) defender.health = 0
                // 大爆炸
                for (let i = 0; i < 12; i++) {
                    const angle = (i / 12) * Math.PI * 2
                    const bx = Math.cos(angle) * 2.0 + defender.position.x
                    const bz = Math.sin(angle) * 2.0 + defender.position.z
                    const bgeo = new THREE.SphereGeometry(0.3, 12, 12)
                    const bmat = new THREE.MeshStandardMaterial({
                        color: 0xff6600,
                        emissive: 0xff3300,
                        emissiveIntensity: 0.8,
                        transparent: true,
                        opacity: 0.9
                    })
                    const bmesh = new THREE.Mesh(bgeo, bmat)
                    bmesh.position.set(bx, defender.position.y + 1.2, bz)
                    threeState.scene.add(bmesh)
                    attackEffects.value.push({ mesh: bmesh, timeLeft: 0.4 })
                }
                // 中心爆炸
                const centerGeo = new THREE.SphereGeometry(0.8, 16, 16)
                const centerMat = new THREE.MeshStandardMaterial({
                    color: 0xffff00,
                    emissive: 0xffff00,
                    emissiveIntensity: 1,
                    transparent: true,
                    opacity: 0.8
                })
                const centerMesh = new THREE.Mesh(centerGeo, centerMat)
                centerMesh.position.set(defender.position.x, defender.position.y + 1.2, defender.position.z)
                threeState.scene.add(centerMesh)
                attackEffects.value.push({ mesh: centerMesh, timeLeft: 0.5 })
            }
        }

        // 玩家1由键盘控制，玩家2为AI
        const updatePlayer = (player, delta, playerIndex) => {
            if (playerIndex === 1) {
                if (keyState.a) player.position.x -= MOVE_SPEED * delta
                if (keyState.d) player.position.x += MOVE_SPEED * delta
                if ((keyState.w || keyState[' ']) && jumpState.p1OnGround) {
                    jumpState.p1VelY = JUMP_VELOCITY
                    jumpState.p1OnGround = false
                }
                if (keyState.s) player.position.z += MOVE_SPEED * delta
                // 普通攻击
                if (keyState.f) {
                    tryAttack(
                        gameState.player1,
                        gameState.player2,
                        performance.now() / 1000,
                        { value: attackState.p1LastAttack },
                        v => attackState.p1LastAttack = v,
                        1
                    )
                }
                // 大招
                if (keyState.g) {
                    trySuper(
                        gameState.player1,
                        gameState.player2,
                        performance.now() / 1000,
                        { value: superState.p1LastSuper },
                        v => superState.p1LastSuper = v,
                        1
                    )
                }
            }
            // 跳跃物理
            if (playerIndex === 1) {
                if (!jumpState.p1OnGround) {
                    jumpState.p1VelY -= GRAVITY * delta
                    player.position.y += jumpState.p1VelY * delta
                    if (player.position.y <= groundY) {
                        player.position.y = groundY
                        jumpState.p1VelY = 0
                        jumpState.p1OnGround = true
                    }
                }
            } else if (playerIndex === 2) {
                if (!jumpState.p2OnGround) {
                    jumpState.p2VelY -= GRAVITY * delta
                    player.position.y += jumpState.p2VelY * delta
                    if (player.position.y <= groundY) {
                        player.position.y = groundY
                        jumpState.p2VelY = 0
                        jumpState.p2OnGround = true
                    }
                }
            }
            // 边界限制
            player.position.x = Math.max(-BOUNDS.x, Math.min(BOUNDS.x, player.position.x))
            player.position.z = Math.max(-BOUNDS.z, Math.min(BOUNDS.z, player.position.z))
        }

        // AI控制玩家2
        function updateAI(delta) {
            const ai = gameState.player2
            const target = gameState.player1
            // 计算距离
            const dx = target.position.x - ai.position.x
            const dz = target.position.z - ai.position.z
            const dist = Math.sqrt(dx * dx + dz * dz)
            const idealDist = 3.0 + Math.random() * 1.5 // 理想距离2.5-4.5米
            // 移动：保持理想距离
            if (dist > idealDist + 0.5) {
                // 距离太远，靠近
                ai.position.x += Math.sign(dx) * MOVE_SPEED * delta * (0.6 + Math.random() * 0.4)
                ai.position.z += Math.sign(dz) * MOVE_SPEED * delta * (0.6 + Math.random() * 0.4)
            } else if (dist < idealDist - 0.5) {
                // 距离太近，后退
                ai.position.x -= Math.sign(dx) * MOVE_SPEED * delta * (0.5 + Math.random() * 0.3)
                ai.position.z -= Math.sign(dz) * MOVE_SPEED * delta * (0.5 + Math.random() * 0.3)
            } else {
                // 在理想距离内，随机左右移动
                if (Math.random() < 0.02) {
                    aiState.moveDir = Math.random() < 0.5 ? 1 : -1
                }
                ai.position.x += aiState.moveDir * MOVE_SPEED * delta * (0.3 + Math.random() * 0.4)
            }
            // 跳跃（偶尔，更自然）
            if (jumpState.p2OnGround && aiState.jumpCooldown <= 0 && Math.random() < 0.008) {
                jumpState.p2VelY = JUMP_VELOCITY * (0.8 + Math.random() * 0.4)
                jumpState.p2OnGround = false
                aiState.jumpCooldown = 1.5 + Math.random() * 2.0
            }
            // 普通攻击（距离更远也能攻击）
            if (aiState.attackCooldown <= 0 && dist < 3.0 && Math.abs(dz) < 1.5 && Math.random() < 0.3) {
                tryAttack(
                    ai,
                    target,
                    performance.now() / 1000,
                    { value: attackState.p2LastAttack },
                    v => attackState.p2LastAttack = v,
                    -1
                )
                aiState.attackCooldown = 1.0 + Math.random() * 1.0
            }
            // 大招（偶尔，距离更远）
            if (aiState.superCooldown <= 0 && dist < 4.0 && Math.random() < 0.005) {
                trySuper(
                    ai,
                    target,
                    performance.now() / 1000,
                    { value: superState.p2LastSuper },
                    v => superState.p2LastSuper = v,
                    -1
                )
                aiState.superCooldown = 6 + Math.random() * 3
            }
            // 跳跃物理
            if (!jumpState.p2OnGround) {
                jumpState.p2VelY -= GRAVITY * delta
                ai.position.y += jumpState.p2VelY * delta
                if (ai.position.y <= groundY) {
                    ai.position.y = groundY
                    jumpState.p2VelY = 0
                    jumpState.p2OnGround = true
                }
            }
            // 边界限制
            ai.position.x = Math.max(-BOUNDS.x, Math.min(BOUNDS.x, ai.position.x))
            ai.position.z = Math.max(-BOUNDS.z, Math.min(BOUNDS.z, ai.position.z))
            // 冷却计时
            if (aiState.attackCooldown > 0) aiState.attackCooldown -= delta
            if (aiState.superCooldown > 0) aiState.superCooldown -= delta
            if (aiState.jumpCooldown > 0) aiState.jumpCooldown -= delta
        }

        // 修改updateGameLogic，玩家2用AI控制
        const updateGameLogic = (delta) => {
            const { character1, character2 } = threeState
            const { player1, player2 } = gameState
            // 更新玩家1位置
            character1.position.set(
                player1.position.x,
                player1.position.y,
                player1.position.z
            )
            // AI控制玩家2
            updateAI(delta)
            character2.position.set(
                player2.position.x,
                player2.position.y,
                player2.position.z
            )
            // 朝向
            // ...（后续逻辑不变）
            updatePlayer(player1, delta, 1)
            // updatePlayer(player2, delta, 2) // 玩家2不再用键盘控制
            // 检测碰撞
            checkCollisions()
            // 更新游戏时间
            updateGameTime(delta)
            // 检查游戏结束条件
            checkGameOver()
        }

        // 受击闪烁效果
        function updateHitFlash(delta) {
            if (hitFlash.p1 > 0) hitFlash.p1 -= delta
            if (hitFlash.p2 > 0) hitFlash.p2 -= delta
            // 角色透明度变化
            if (threeState.character1) threeState.character1.traverse(obj => {
                if (obj.material) obj.material.opacity = hitFlash.p1 > 0 ? 0.4 : 1
                if (obj.material) obj.material.transparent = hitFlash.p1 > 0
            })
            if (threeState.character2) threeState.character2.traverse(obj => {
                if (obj.material) obj.material.opacity = hitFlash.p2 > 0 ? 0.4 : 1
                if (obj.material) obj.material.transparent = hitFlash.p2 > 0
            })
        }

        // 检测碰撞
        const checkCollisions = () => {
            // 检测玩家攻击是否命中对方
            gameState.player1.attacks.forEach(attack => {
                if (checkHit(attack, gameState.player2)) {
                    gameState.player2.health -= attack.damage
                    // 可以添加命中效果
                }
            })

            gameState.player2.attacks.forEach(attack => {
                if (checkHit(attack, gameState.player1)) {
                    gameState.player1.health -= attack.damage
                    // 可以添加命中效果
                }
            })

            // 清除已处理的攻击
            gameState.player1.attacks = gameState.player1.attacks.filter(a => !a.processed)
            gameState.player2.attacks = gameState.player2.attacks.filter(a => !a.processed)
        }

        // 检测命中
        const checkHit = (attack, target) => {
            // 简单的碰撞检测
            const distance = Math.sqrt(
                Math.pow(attack.position.x - target.position.x, 2) +
                Math.pow(attack.position.y - target.position.y, 2) +
                Math.pow(attack.position.z - target.position.z, 2)
            )
            return distance < attack.radius
        }

        // 更新游戏时间
        const updateGameTime = (delta) => {
            gameState.time -= delta
            if (gameState.time <= 0) {
                gameState.time = 0
                gameState.gameOver = true
                // 可以添加时间结束逻辑
            }
        }

        // 检查游戏结束
        const checkGameOver = () => {
            if (gameState.player1.health <= 0 || gameState.player2.health <= 0) {
                gameState.gameOver = true
                // 可以添加游戏结束逻辑
            }
        }

        // 处理窗口大小变化
        const handleResize = () => {
            const { camera, renderer, composer } = threeState
            camera.aspect = window.innerWidth / window.innerHeight
            camera.updateProjectionMatrix()
            renderer.setSize(window.innerWidth, window.innerHeight)
            if (composer) {
                composer.setSize(window.innerWidth, window.innerHeight)
            }
        }

        // 监听键盘事件，支持三维移动和大招
        function handleKeyDown(e) {
            const k = e.key.toLowerCase()
            if (k in keyState) keyState[k] = true
        }
        function handleKeyUp(e) {
            const k = e.key.toLowerCase()
            if (k in keyState) keyState[k] = false
        }

        // 角色始终面向对手
        function updateCharacterFacing() {
            if (threeState.character1 && threeState.character2) {
                const p1 = gameState.player1.position
                const p2 = gameState.player2.position
                const dx = p2.x - p1.x
                const dz = p2.z - p1.z
                const angle = Math.atan2(dx, dz)
                threeState.character1.rotation.y = angle
                threeState.character2.rotation.y = angle + Math.PI
            }
        }

        // 攻击/受击动画（简单手臂前伸/身体后仰）
        function updateCharacterAction() {
            // 玩家1攻击时手臂前伸
            if (threeState.character1) {
                threeState.character1.traverse(obj => {
                    if (obj.name === 'leftArm' || obj.name === 'rightArm') {
                        obj.position.z = keyState.f ? 0.5 : 0
                    }
                    if (obj.name === 'body') {
                        obj.rotation.x = hitFlash.p1 > 0 ? -0.5 : 0
                    }
                })
            }
            if (threeState.character2) {
                threeState.character2.traverse(obj => {
                    if (obj.name === 'leftArm' || obj.name === 'rightArm') {
                        obj.position.z = keyState.h ? 0.5 : 0
                    }
                    if (obj.name === 'body') {
                        obj.rotation.x = hitFlash.p2 > 0 ? -0.5 : 0
                    }
                })
            }
        }

        // 动画循环
        const animate = () => {
            if (gameState.gameOver) {
                endGame()
                return
            }
            threeState.animationFrameId = requestAnimationFrame(animate)
            const delta = Math.min(threeState.clock.getDelta(), 0.1)
            if (threeState.mixer1) threeState.mixer1.update(delta)
            if (threeState.mixer2) threeState.mixer2.update(delta)
            updateGameLogic(delta)
            updateAttackEffects(delta)
            updateAttackTrails(delta)
            updateHitFlash(delta)
            updateCharacterFacing()
            updateCharacterAction()
            try {
                if (threeState.composer) {
                    threeState.composer.render()
                } else {
                    threeState.renderer.render(threeState.scene, threeState.camera)
                }
            } catch (e) {
                console.error('渲染错误:', e)
            }
        }

        // 游戏结束弹窗提示
        function endGame() {
            setTimeout(() => {
                const winner = gameState.player1.health > 0 ? '玩家1' : '玩家2'
                alert(`游戏结束！${winner} 获胜！`)
                // 可以自动返回菜单或重置
            }, 300)
        }

        // 清理资源
        const cleanupResources = () => {
            const { scene, renderer, composer, mixer1, mixer2, animationFrameId } = threeState

            if (animationFrameId) {
                cancelAnimationFrame(animationFrameId)
            }

            if (mixer1) mixer1.stopAllAction()
            if (mixer2) mixer2.stopAllAction()

            scene.traverse(obj => {
                if (obj.material) {
                    obj.material.dispose()
                }
                if (obj.geometry) {
                    obj.geometry.dispose()
                }
                if (obj.texture) {
                    obj.texture.dispose()
                }
            })

            renderer.dispose()
            if (composer) {
                composer.dispose()
            }
        }

        // 生命周期挂载和卸载
        onMounted(() => {
            initScene()
            window.addEventListener('resize', handleResize)
            window.addEventListener('keydown', handleKeyDown)
            window.addEventListener('keyup', handleKeyUp)
        })

        onUnmounted(() => {
            window.removeEventListener('resize', handleResize)
            window.removeEventListener('keydown', handleKeyDown)
            window.removeEventListener('keyup', handleKeyUp)
            cleanupResources()
        })

        // 计算冷却时间
        const getAttackCooldown = () => {
            const now = performance.now() / 1000
            const timeSinceLastAttack = now - attackState.p1LastAttack
            return Math.max(0, ATTACK_COOLDOWN - timeSinceLastAttack)
        }

        const getSuperCooldown = () => {
            const now = performance.now() / 1000
            const timeSinceLastSuper = now - superState.p1LastSuper
            return Math.max(0, SUPER_COOLDOWN - timeSinceLastSuper)
        }

        return {
            container,
            gameState,
            attackState,
            superState,
            getAttackCooldown,
            getSuperCooldown
        }
    }
}
</script>

<style lang="scss" scoped>
.game-stage {
    position: relative;
    width: 100%;
    height: 100%;

    .three-container {
        width: 100%;
        height: 100%;
    }
}

.skills-ui {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 10px;
    background-color: rgba(0, 0, 0, 0.5);
    display: flex;
    gap: 40px;
    z-index: 10;

    .skill-section {
        margin-bottom: 10px;

        h3 {
            margin-bottom: 5px;
            color: #ffcc00;
            font-size: 1.1rem;
            text-shadow: 0 0 6px #000;
        }

        .skill-row {
            display: flex;
            align-items: center;
            margin-bottom: 8px;

            .skill-key {
                width: 40px;
                height: 40px;
                background: radial-gradient(circle at 30% 30%, #fff 70%, #ccc 100%);
                border: 3px solid #222;
                border-radius: 50%;
                box-shadow: 0 2px 8px #0008;
                color: #222;
                font-weight: bold;
                font-size: 1.3rem;
                display: flex;
                align-items: center;
                justify-content: center;
                margin-right: 12px;
                position: relative;
                transition: background 0.2s;
                text-shadow: 0 0 2px #fff, 0 0 6px #000;

                &.cooldown {
                    background: repeating-linear-gradient(135deg, #888 0 10px, #bbb 10px 20px);
                    color: #fff;
                    border-color: #ff4444;
                }

                .cooldown-mask {
                    position: absolute;
                    top: 0;
                    left: 0;
                    right: 0;
                    bottom: 0;
                    background: rgba(80, 80, 80, 0.6);
                    border-radius: 50%;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                }

                .cooldown-num {
                    color: #fff;
                    font-size: 1.1rem;
                    font-weight: bold;
                    text-shadow: 0 0 4px #000, 0 0 2px #fff;
                }
            }

            span {
                flex: 1;
                color: #fff;
                font-size: 1rem;
                text-shadow: 0 0 4px #000;
            }
        }
    }
}

.next-level-modal {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 100;

    .modal-content {
        background: #222;
        border-radius: 12px;
        padding: 32px 40px;
        box-shadow: 0 4px 32px #000a;
        display: flex;
        flex-direction: column;
        align-items: center;

        .modal-title {
            color: #ffcc00;
            font-size: 2rem;
            margin-bottom: 24px;
        }

        .next-btn,
        .back-btn {
            margin: 8px 0;
            padding: 10px 32px;
            font-size: 1.2rem;
            border-radius: 6px;
            border: none;
            background: linear-gradient(90deg, #ffcc00, #ff8800);
            color: #222;
            font-weight: bold;
            cursor: pointer;
            transition: background 0.2s;
        }

        .back-btn {
            background: #444;
            color: #fff;
        }
    }
}
</style>